import * as Koa from 'koa';
import * as jwt from 'koa-jwt';
import "reflect-metadata";
import * as path from 'path';
import * as winston from 'winston';
import * as static_ from 'koa-static';
// import * as helmet from 'helmet';
import * as bodyParser from 'koa-bodyparser';
import { createConnection } from 'typeorm';
import * as dotenv from 'dotenv';
import { error } from './utils/error-handle/error-info';
// import { ip } from './utils/ip';
// import * as fs from 'fs';

process.stdout.write(`[Info] Loading environment params and database ini ... \n`);
dotenv.config();// 加载配置&环境参数
process.stdout.write(`[Info] Loading complete \n`);

import { config } from './config/config';
import { router } from "./routers/index";
import { logger } from "./utils/log";
import { response } from './utils/response';
import handle from './utils/error-handle';
import { crawlingNBAData } from './nba/nba';

// import * as child_process from 'child_process';

process.stdout.write(`[Info] Connecting Mysql Database ... \n`);

/**
 * 这边，我要吐槽。。。
 * typescript，真是特么想说爱你很难啊。。。这特么，typeorm说是支持ts，结果加载实例的类地址还要判断当前环境（因为发布之后编译成js，路径就不对了。）。
 * 还有，我的环境变量是配置在.env文件中的，每次debug，还要手动改配置，贼蠢（需要debug编译后的情况，必须改成production环境）。当然我试了 在package.json scripts中 先set NODE_ENV 然后进行后续操作，但是为什么 development === development 是false。。。
 */
const envs: string = process.env.NODE_ENV;
const entities: string[] = envs === 'development' ? [
    'src/database/entity/**/*.ts'
] : [
    path.resolve(__dirname,"./database/entity/**/*.js")
];

createConnection({
    type: 'mysql',
    host: config.databaseHost,
    port: config.databasePort,
    username: config.databaseUserName,
    password: config.databasePassword,
    database: config.databaseDB,
    synchronize: true, // 是否同步表结构
    logging: true,
    cache: {
        duration: 180000
    },
    entities,
    // entities: [
    //     // 'src/database/entity/**/*.ts',// 开发时用这个
    //     'dist/database/entity/**/*.js'// 编译之后运行用这个
    // ],
}).then(async connection => {
    process.stdout.write(`[success] Connect Mysql Database succeed \n`);
    const app = new Koa();
    const port = config.port;

    // const file = path.join(__dirname,"utils/error-handle/error-info.json");
    // const content = fs.readFileSync(file,"utf-8");
    const errorInfo = error;

    app.use(async (ctx,next) => {// 这边处理系统源码中app.emit('error')触发的错误处理
        try{
            ctx.util = {
                response
            }
            ctx.ERROR = errorInfo;
            await next();
        }catch(error) {
            const code = error.code || ctx.ERROR.ERRORCODE_SYSTEMERROR;
            const message = error.message || ctx.ERROR.ERRORMSG_SYSTEMERROR;
            const value = error.value || {};
            ctx.body = response(code,message,value);
        }
    })

    // app.use(helmet());

    app.use(bodyParser());

    app.use(logger(winston));

    app.use(static_(
        path.join(__dirname, '../public')
    ))

    app.use(jwt({ secret: config.jwtSecret }).unless({
        path: [/^\/api\/login/,/^\/api\/users/,/^\/api\/logout/]
    }));

    app.use(router.routes()).use(router.allowedMethods()) // 引入返回"Method Not Allowed - 405"的中间件;

    app.use(async (ctx,next) => {// router没找到就走到这，所以是处理404的
        // console.log('404 not found');
        ctx.body = ctx.util.response(ctx.response.status,ctx.response.message);
    })

    app.on("error",handle());//ctx.app.emit('error')的统一错误处理

    app.listen(port);

    //crawlingNBAData(); // 开始爬取nba数据 子进程中拿不到数据库实例，暂时方式使用子进程

    process.stdout.write(`[Info] Server running on : http://127.0.0.1:${port} \n`);
}).catch(error => process.stdout.write(`[Error] TypeORM 连接数据库失败：${error};数据库地址：${config.databaseHost}:${config.databasePort};用户名：${config.databaseUserName};密码：${config.databasePassword};数据库：${config.databaseDB} \n`))